package cate.game.role.bag.storehouse;

import cate.common.table.d.GDBag;
import cate.common.table.d.GDObj;
import cate.common.table.item.IBagItemTpl;
import cate.common.util.GameResult;
import cate.game.client.msg.MergeMsgSender;
import cate.game.res.RewardShow;
import cate.game.role.Role;
import cate.game.role.bag.BagContainer;
import cate.game.role.bag.item.msg.ItemAddResp;
import cate.game.role.bag.prop.Prop;
import cate.game.role.bag.storehouse.msg.PropStorehouseAddResp;
import cate.game.role.bag.storehouse.msg.StoreHouseItemNumResp;
import cate.game.role.bag.storehouse.msg.StoreHouseItemRemoveResp;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class StoreHouse extends BagContainer<Prop> {

    public StoreHouse() {
    }

    public StoreHouse(Role role){
        super(role);
    }
    @Override
    public int calcCapacity() {
        return GDBag.Capcity.PROP_STOREHOUSE;
    }

    @Override
    public IBagItemTpl getItemTpl(int templateId) {
        return role.getGame().table.item.base.get(templateId);
    }

    @Override
    protected byte getItemType() {
        return GDObj.Type.PROP;
    }

    @Override
    protected ItemAddResp<PropStorehouseAddResp> createItemAddMsg() {
        return new PropStorehouseAddResp();
    }

    @Override
    protected Prop createItem(int tid, long num) {
        return new Prop(role, tid, num);
    }

    /** 添加 */
    @Override
    public GameResult<Void> addItem(int tid, long num, MergeMsgSender sender) {
        GameResult<Void> r = addItemCheck(tid, num);
        if (!r.ok()) {
            return r;
        }
        StoreHouseItemNumResp numMsg = new StoreHouseItemNumResp(getItemType()); // 物品数量变更的消息
        IBagItemTpl tpl = getItemTpl(tid);
        long leftToAdd = num;
        for (Prop item : this.getList()) {
            if (leftToAdd <= 0) {
                break;
            }
            if (item.tid != tpl.getTemplateId() || item.getTpl(role.toPlayBuildContext()).unique()) {
                continue;
            }
            // 该物品格子的剩余可堆叠数量
            long itemLeftNum = tpl.getPileMax() - item.num;
            if (itemLeftNum > 0) {
                long toAdd = Math.min(itemLeftNum, leftToAdd);
                item.addNum(toAdd);
                leftToAdd -= toAdd;
                numMsg.addChange(item.uid, item.num);
            }
        }
        if (!numMsg.changes.isEmpty()) {
            MergeMsgSender.handle(sender, numMsg, this.role);
        }
        // 如果还有没堆叠完的，就要创建新的物品项
        if (leftToAdd > 0) {
            List<Prop> items = new ArrayList<>();
            ItemAddResp<PropStorehouseAddResp> addMsg = createItemAddMsg();
            int newGridNum = (int) Math.ceil((double) leftToAdd / tpl.getPileMax());
            for (int i = 0; i < newGridNum; i++) {
                long toAdd = Math.min(leftToAdd, tpl.getPileMax());
                leftToAdd -= toAdd;
                Prop item = createItem(tid, toAdd);
                if (item != null) {
                    this.getList().add(item);
                    items.add(item);
                    addMsg.add(item);
                }
            }
            MergeMsgSender.handle(sender, addMsg, this.role);
            for (Prop e : items) {
                onItemCreated(e);
            }
        }
        // 统计需要放在最后
        onItemIncreased(tid, num);
        return r;
    }


    /** 移除背包中的指定物品 */
    @Override
    public GameResult<RewardShow> removeItem(String uid, MergeMsgSender sender) {
        GameResult<RewardShow> r = new GameResult<>();
        Iterator<Prop> iterator = this.getList().iterator();
        while (iterator.hasNext()) {
            Prop item = iterator.next();
            if (StringUtils.equals(item.uid, uid)) {
                iterator.remove();
                onItemRemoved(item);
                MergeMsgSender.handle(sender, new StoreHouseItemRemoveResp(item.uid, item.type),role);
                onItemDecreased(item.tid, item.num);
                return r.success("删除物品成功");
            }
        }
        return r.fail("物品不存在");
    }

    /** 删除或扣除 */
    @Override
    public GameResult<RewardShow> removeItem(int tid, long num, MergeMsgSender sender) {
        GameResult<RewardShow> r = new GameResult<>();
        if (num < 0) {
            return r.fail("非法数据");
        }
        long total = count(tid);
        if (num > total) {
            return r.fail("数量不够");
        }
        // 待移除的数量
        long numRm = num;
        StoreHouseItemRemoveResp removeResp = null;
        Iterator<Prop> iterator = this.getList().iterator();
        while (iterator.hasNext()) {
            Prop item = iterator.next();
            if (item.tid == tid) {
                if (item.moreThan(numRm)) {
                    item.addNum(-numRm);
                    numRm = 0;
                    MergeMsgSender.handle(sender, new StoreHouseItemNumResp(item.type).addChange(item.uid, item.num),role);
                } else {
                    iterator.remove();
                    onItemRemoved(item);
                    if(removeResp == null){
                        removeResp = new StoreHouseItemRemoveResp(item.type);
                    }
                    removeResp.add(item.uid);
                    numRm -= item.num;
                }
            }
            if (numRm <= 0) {
                break;
            }
        }
        if(removeResp != null){
            MergeMsgSender.handle(sender,removeResp,role);
        }
        onItemDecreased(tid, num);
        return r.success();
    }

}


